﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using FxSuperCore.Log;
using FxSuperCore.Utils;
using FxWinSuper.Functions;
using FxWinSuper.Plugin;
using FxWinSuper.UI.Controls;
using FxWinSuper.UI.Menu;
using FxWinSuper.UI.Menu.Pages;
using FxWinSuper.Util;
using FxWinSupper.Config;
using HandyControl.Controls;
using NotifyIcon = HandyControl.Controls.NotifyIcon;
using Timer = System.Threading.Timer;


namespace FxWinSuper
{
	/// <summary>
	/// MainWindow.xaml 的交互逻辑
	/// </summary>
	internal partial class MainWindow : System.Windows.Window
	{
		public static MainWindow Instance { get; private set; }
		public IntPtr WinHandle { get; private set; }

		private ILogPrint Logger = null;
		private Dictionary<string, SliderMenuData> sideMenuDic = new Dictionary<string, SliderMenuData>(20);
		private Timer ConfigFlushTimer;
		private const int FlushConfigTimeInterval = 5 * 60 * 1000;
		private NotifyIcon _notifyIcon;

		public static readonly string MainThreadName = "FxWinSupperMainUIThread";

		public MainWindow()
		{
			Instance = this;
			InitializeComponent();
			Loaded += (o, e) => Activate();
			Closing += MainWindow_Closing;
			Thread.CurrentThread.Name = MainThreadName;
			WinHandle = new WindowInteropHelper(this).Handle;
			InitView();
		}

		private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			CloseNotifyIconContextMenu();
			ConfigFlushTimer?.Dispose();
			_notifyIcon?.Dispose();
		}

		public void Invoke(Action action) => Dispatcher.Invoke(action);

		private void InitView()
		{
			Conf.LoadConf();
			Logger = InternalLog.Instance;
			InitSideMenu();
			InitNotifyIcon();
			PluginController.LoadPlugins();
			ConfigFlushTimer = new Timer(TimerForSaveConfig, null, FlushConfigTimeInterval, FlushConfigTimeInterval);
			if (Conf.Upgrated)
			{
				CommonUtils.ShowWinToast("提示", $"软件已成功升级到版本[{Conf.Version}]", System.Windows.Forms.ToolTipIcon.Info, 5000);
			}
		}

		private void InitNotifyIcon()
		{
			_notifyIcon = new NotifyIcon();
			_notifyIcon.Icon = new BitmapImage(new Uri("pack://application:,,,/FxWinSupper/Resource/fx32.ico"));
			var menu = new FxContextMenu();
			menu.AddSubItem(new FxContextMenuItem()
			{
				Icon = new BitmapImage(new Uri("pack://application:,,,/FxWinSupper/Resource/about.png")),
				Title = "关于",
				Click = () => new AboutWindow().ShowDialog()
			});
			menu.AddSubItem(new FxDivider());
			menu.AddSubItem(new FxContextMenuItem()
			{
				Icon = new BitmapImage(new Uri("pack://application:,,,/FxWinSupper/Resource/exit.png")),
				IconWidth = 14,
				IconHeight = 14,
				Title = "退出",
				Click = () =>
				{
					CloseNotifyIconContextMenu();
					ApplicationUtil.Exit();
				}
			});
			_notifyIcon.ContextContent = menu;
			_notifyIcon.Init();
		}

		/// <summary>
		/// 关闭托盘图标已经展开的菜单项
		/// </summary>
		public void CloseNotifyIconContextMenu()
		{
			_notifyIcon?.CloseContextControl();
		}

		/// <summary>
		/// 注册一个托盘右键菜单子项
		/// </summary>
		/// <param name="subItem">子组件</param>
		public void RegisterContextMenuItem(UIElement subItem)
		{
			_notifyIcon?.Let(it =>
			{
				FxContextMenu meun = it.ContextContent as FxContextMenu;
				meun.InsertBeforeSubItem(subItem);
			});
		}

		/// <summary>
		/// 注册一个托盘右键菜单子项
		/// </summary>
		/// <param name="subItem">子组件</param>
		public void RegisterContextMenuItem(FxContextMenuItem subItem)
		{
			_notifyIcon?.Let(it =>
			{
				FxContextMenu meun = it.ContextContent as FxContextMenu;
				meun.InsertBeforeSubItem(subItem);
			});
		}

		private void InitSideMenu()
		{
			RegisterSliderMenu("首页", new Image()
			{
				Source = new BitmapImage(new Uri("pack://application:,,,/FxWinSupper/Resource/home.png")),
				Width = 16,
				Height = 16
			}, () => new HomePage());
			RegisterSliderMenu("日志", new Image()
			{
				Source = new BitmapImage(new Uri("pack://application:,,,/FxWinSupper/Resource/log.png")),
				Width = 22,
				Height = 22
			}, new LogPage());
			RegisterSliderMenu("插件", new Image()
			{
				Source = new BitmapImage(new Uri("pack://application:,,,/FxWinSupper/Resource/plugin.png")),
				Width = 16,
				Height = 16
			}, () => new PluginPage());
			uiSideMenu.SelectionChanged += (sender, e) =>
			{
				SideMenuItem sideMenuItem = e.Info as SideMenuItem;
				uiPageContent.Content = sideMenuDic[sideMenuItem.Header.ToString()].CurrentPage;
			};
			// 选中第一项
			uiSideMenu.Loaded += (s, e) => SelectSideMenuItem(uiSideMenu.Items[0] as SideMenuItem);
		}

		/// <summary>
		/// 窗体关闭事件
		/// </summary>
		private void OnWindowClosed(object sender, EventArgs e)
		{
			PluginController.ExitPlugins();
			ConfigFlushTimer?.Dispose();
			Conf.SaveConf();
		}

		/// <summary>
		/// 定时保存配置
		/// </summary>
		private void TimerForSaveConfig(object state)
		{
			Dispatcher.Invoke(() => Conf.SaveConf());
		}

		public void SwitchPage(string PageTitle)
		{
			if (!sideMenuDic.ContainsKey(PageTitle))
			{
				Logger.Error($"切换界面失败:未找到界面标题[{PageTitle}]");
				CommonUtils.ShowWinToast("提示", $"未找到[{PageTitle}]页");
				return;
			}

			foreach (SideMenuItem item in uiSideMenu.Items)
			{
				if (item.Header.ToString() == PageTitle)
				{
					SelectSideMenuItem(item);
					break;
				}
			}
		}

		private void SelectSideMenuItem(SideMenuItem menuItem)
		{
			MethodInfo OnMouseLeftButtonDown = menuItem.GetType().GetMethod("OnMouseLeftButtonDown", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo OnMouseLeftButtonUp = menuItem.GetType().GetMethod("OnMouseLeftButtonUp", BindingFlags.Instance | BindingFlags.NonPublic);
			OnMouseLeftButtonDown.Invoke(menuItem, new object[] {null});
			OnMouseLeftButtonUp.Invoke(menuItem, new object[] {null});
		}

		/// <summary>
		/// 注册一个侧边栏菜单
		/// </summary>
		public void RegisterSliderMenu(string header, Image icon, Func<Page> getPage)
		{
			if (header == null || icon == null || getPage == null)
			{
				throw new NullReferenceException("slider menu item has null params");
			}

			if (sideMenuDic.ContainsKey(header))
			{
				throw new ArgumentException("already same name menu item");
			}
			SliderMenuData sliderMenuData = new SliderMenuData(header, icon, getPage);
			sideMenuDic.Add(header, sliderMenuData);
			uiSideMenu.Items.Add(new SideMenuItem()
			{
				Icon = icon,
				Header = header
			});
		}

		/// <summary>
		/// 注册一个侧边栏菜单
		/// </summary>
		public void RegisterSliderMenu(string header, Image icon, Page page)
		{
			if (header == null || icon == null || page == null)
			{
				throw new NullReferenceException("slider menu item has null params");
			}

			if (sideMenuDic.ContainsKey(header))
			{
				throw new ArgumentException("already same name menu item");
			}
			SliderMenuData sliderMenuData = new SliderMenuData(header, icon, page);
			sideMenuDic.Add(header, sliderMenuData);
			uiSideMenu.Items.Add(new SideMenuItem()
			{
				Icon = icon,
				Header = header
			});
		}

		private void ShowAboutPage(object sender, MouseButtonEventArgs e)
		{
			new AboutWindow().ShowDialog(); 
		}

		protected override void OnActivated(EventArgs e)
		{
			base.OnActivated(e);
			Growl.SetGrowlParent(GrowlPanel, true);
		}

		protected override void OnDeactivated(EventArgs e)
		{
			base.OnDeactivated(e);
			Growl.SetGrowlParent(GrowlPanel, false);
		}
	}
}
